﻿using System.Collections;
using System.Collections.Generic;
using Protocol.Code;
using Protocol.Dto.Fight;
using Script.Framework;
using Script.Model;
using Script.UI;
using Script.UI.Msg;
using UnityEngine;

namespace Script.Character
{
    public class MyPlayerCtrl : CharacterBase
    {
        // Other UI object
        private PromptMsg promptMsg;

        // Logic Object
        private SocketMsg socketMsg;

        private void Awake()
        {
            Bind(CharacterEvent.INIT_MY_CARD,
                CharacterEvent.ADD_MY_CARD,
                CharacterEvent.DEAD_CARD,
                CharacterEvent.REMOVE_MY_CARD);
        }

        public override void Execute(int eventCode, object message)
        {
            switch (eventCode)
            {
                case CharacterEvent.INIT_MY_CARD:
                    StartCoroutine(InitCardList(message as List<CardDto>));
                    break;
                case CharacterEvent.ADD_MY_CARD:
                    AddTableCard(message as GrabDto);
                    break;
                case CharacterEvent.DEAD_CARD:
                    dealSelectCard();
                    break;
                case CharacterEvent.REMOVE_MY_CARD:
                    RemoveCard(message as List<CardDto>);
                    break;
            }
        }

        // List

        // 自身的卡牌列表
        [SerializeField] private List<CardCtrl> cardCtrlList;

        // 卡牌的父物体
        private Transform cardParent;
        private GameObject cardPrefab;


        private void Start()
        {
            cardParent = transform.Find("CardPoint");
            cardCtrlList = new List<CardCtrl>();

            promptMsg = new PromptMsg();

            socketMsg = new SocketMsg();
        }


        /// <summary>
        /// 出选择的牌
        /// </summary>
        private void dealSelectCard()
        {
            List<CardDto> cardList = getSelectCard();

            DealDto dto = new DealDto(cardList, Models.GameModel.Id);


            // 如果出牌不合法

            if (dto.isRegular == false)
            {
                Dispatch(AreaCode.UI, UIEvent.SHOW_DEAL_BUTTON, true);

                promptMsg.Change("请选择合理的手牌！", Color.red);

                Dispatch(AreaCode.UI, UIEvent.PROMPT_MSG, promptMsg);

                // 显示出牌按钮
                Dispatch(AreaCode.UI, UIEvent.SHOW_DEAL_BUTTON, true);
            }
            else
            {
                // 可以出牌
                socketMsg.Change(OpCode.FIGHT, FightCode.DEAL_CREQ, dto);

                Dispatch(AreaCode.NET, 0, socketMsg);
            }
        }

        /// <summary>
        /// 移除卡牌的游戏的物体
        /// </summary>
        private void RemoveCard(List<CardDto> remainCardList)
        {
            int index = 0;
            foreach (CardCtrl cardCtrl in cardCtrlList)
            {
                if (remainCardList.Count == 0)
                {
                    break;
                }
                else
                {
                    cardCtrl.gameObject.SetActive(true);
                    cardCtrl.Init(remainCardList[index], index, true);
                    index++;

                    if (index == remainCardList.Count)
                    {
                        break;
                    }
                }
            }

            for (int i = index; i < cardCtrlList.Count; i++)
            {
                cardCtrlList[i].Selected = false;
                cardCtrlList[i].gameObject.SetActive(false);
            }
        }

        /// <summary>
        /// 获取选中的牌
        /// </summary>
        /// <returns></returns>
        private List<CardDto> getSelectCard()
        {
            List<CardDto> select = new List<CardDto>();

            foreach (CardCtrl cardCtrl in cardCtrlList)
            {
                if (cardCtrl.Selected)
                {
                    select.Add(cardCtrl.mCardDto);
                }
            }

            return select;
        }


        /// <summary>
        /// 根据服务器返回的自己的牌的信息
        /// 用线程睡眠来做一个发牌的动画
        /// </summary>
        /// <param name="cardDtoList">服务器发给我的牌的对象（CardDto）列表</param>
        /// <returns></returns>
        private IEnumerator InitCardList(List<CardDto> cardDtoList)
        {
            cardPrefab = Resources.Load<GameObject>("Card/MyCard");

            for (int i = 0; i < cardDtoList.Count; i++)
            {
                CreateGo(cardDtoList[i], i, cardPrefab);

                yield return new WaitForSeconds(0.1f);
            }
        }


        /// <summary>
        /// 创建卡牌游戏物体
        /// </summary>
        /// <param name="cardDto"></param>
        /// <param name="index"></param>
        /// <param name="prefab"></param>
        private void CreateGo(CardDto cardDto, int index, GameObject prefab)
        {
            GameObject card = Instantiate(prefab, cardParent);

            card.name = cardDto.Name;

            CardCtrl cardCtrl = card.GetComponent<CardCtrl>();

            cardCtrl.Init(cardDto, index, true);


            // 存储本地
            cardCtrlList.Add(cardCtrl);
        }

        /// <summary>
        /// 添加底牌
        /// </summary>
        private void AddTableCard(GrabDto grabDto)
        {
            // List<CardDto> tableCards = grabDto.tableCardList;
            List<CardDto> playerCardList = grabDto.PlayerCardList;

            // 复用之前创建的卡牌
            int index = 0;

            foreach (CardCtrl cardCtrl in cardCtrlList)
            {
                cardCtrl.gameObject.SetActive(true);
                cardCtrl.Init(playerCardList[index], index, true);
                index++;
            }

            for (int i = index; i < playerCardList.Count; i++)
            {
                CreateGo(playerCardList[i], i, cardPrefab);
            }
        }
    }
}